#include <iostream>
#include <cstring>
#include <functional>

using namespace std;

// 第一个版本，可以比较任意两个类型
template <typename T> int compare(const T& v1, const T& v2)
{
    cout << "compare edition 1" << endl;
    if (less<T>()(v1, v2)) return -1;
    if (less<T>()(v2, v1)) return 1;
    return 0;
}

// 第二个版本，处理字符串字面常量
template<size_t N, size_t M>
int compare(const char (&r1)[N], const char (&r2)[M])
{
    cout << "compare edition 2" << endl;
    return strcmp(r1, r2);
}

/**
 * 第二个版本的特例化版本
 * 
 * <> 表示我们将为原模板的所有模板参数提供实参
 * 一个特例化版本本质上是一个实例（显式实例化），而非函数名的一个重载版本
 * 特例化版本丢失：原模板的一个实例具有相同的模板实参集合
 */
template <>
int compare(const char* const &p1, const char* const &p2)
{
    cout << "compare edition 2 special" << endl;
    return strcmp(p1, p2);
}

int main()
{
    const char *p1 = "hi", *p2 = "mom";
    /**
     * 没有第二个版本的特例化版本时，
     * 调用第一个版本（第二个版本无法将指针转换为数组的引用）；
     * 有第二个版本的特例化版本时，
     * 调用第二个版本的特例化版本
     */
    compare(p1, p2); 
    // 调用第二个版本
    compare("hi", "mom");
}